/**************************************************************************
 * @doc rcptcmpt
 * @module prtfuncs.C
 * Source for the receipt and report functions.
 *
 * Product     :   SoftPay 2000 (Global Payment Methodology).
 * <nl>Developer   :
 * <nl>Notes       :
 *
 * @head3 rcptcmpt Functions |
 * @index | Functions
 * @end
 *
 * Copyright (c) 1996-2000 by VeriFone Inc. All rights reserved.
 *
 * No part of this software may be used, stored, compiled, reproduced,
 * modified, transcribed, translated, transmitted, or transferred, in any form
 * or by any means whether electronic, mechanical, magnetic, optical,
 * or otherwise, without the express prior written permission of VeriFone, Inc.
 *
 * Revision History
 * ------------------------------------------------------------------------
 $Log: /SoftPay/SPK2SIM/Source/rcptcmpt/prtfuncs.c $
 ********************************************************************************/

#include <stdio.h>
#include <aclstr.h>
#include <svc.h>
#include <string.h>
#include <acldev.h>

#include <project.h>

#ifdef DEBUG_PRTFUNCS_C
#define DEBUG_95
#endif

#include <define.h>
#include <spdebug.h>
#include <transact.h>
#include <tran.h>
#include <comm.h>
#include <confproto.h>
#include <trt.h>
#include <msg.h>
#include <recptfrm.h>
#include <print.h>
#include <form.h>
#include <funcids.h>
#include <table.h>
#include <entry.h>
#include <ui.h>
#include <date.h>
#include <pfr.h>
#include <init.h>
#include <msgfuncs.h>
#include <mdlfuncs.h>

#include <rcptcmpt.h>
#include <rcptsegs.h>
#include <prtfuncs.h>
#include <codesec.h>
#include <msngr.h>

FUNCTION_TABLE srPrintFuncs[] = {
    {inPrintReceiptTop,             PRINT_RCPT_TOP},
    {inPrintReceiptBottom,          PRINT_RCPT_BOTTOM},
    {inPrinterCheck,                PRINTER_CHECK},
    {inPreprint,                    PREPRINT},
    {inFlowPrintReceipt,            PRINT_RECEIPT},
    {inPrintErrorMsg,               PRINT_ERR_MSG},
    {inPrintReceiptMiddle,          PRINT_RCPT_MIDDLE},
    {inSetReceiptTopConditions,     SET_RCPT_TOP_COND},
    {inSetReceiptBottomConditions,  SET_RCPT_BOTTOM_COND},
    {inSetReceiptMiddleConditions,  SET_RCPT_MIDDLE_COND},
    {inMakeReceiptTop,              MAKE_RCPT_TOP},
    {inMakeReceiptAfterResp,        MAKE_RCPT_AFTER},
    {inPrintReceiptHeader,          PRINT_RCPT_HEADER},
    {inMakeReceiptAmount,           MAKE_RCPT_AMOUNT},
    #ifdef MESSENGER_DEFINED
    {inPrintMessengerVoucher,       PRINT_MSNGR_VOUCHER},
    {inPrintMessengerReport,         PRINT_MSNGR_REPORT},
    #endif
    {0,                             END_OF_FUNC_TABLE},

};

/*********************************************************************************************
* @func int | inAddPrintFunctions |
*       Adds Print flow functions and form functions to the flexi record.
*
* @rdesc return values.
* @flag int    |  VS_ERR, VS_ESCAPE or VS_SUCCESS
* @end
**********************************************************************************************/

int inAddPrintFunctions(void) {
    int inCount = 0;

    /* Add PRINT functions to the flexi record */
    do {
        if (inAddFunctionPointer(srPrintFuncs[inCount].inFieldID, srPrintFuncs[inCount].pinFunction) == VS_ERR)
            return (VS_ERR);
        inCount++;
    } while (srPrintFuncs[inCount].inFieldID != END_OF_FUNC_TABLE);

    return(VS_SUCCESS);
}


/*********************************************************************************************
* @func VS_BOOL | fCustomerReceipt |
*       Determine if customer receipt should be printed by prompting
*                    the user.
*
* @parm TRANSACTION_OBJECT *| pobTran
*       Transaction object
*
* @rdesc return values.
* @flag int    |  VS_TRUE
* @flag int    |  VS_FALSE
* @end
**********************************************************************************************/

VS_BOOL fCustomerReceipt(TRANSACTION_OBJECT* pobTran) {
    int     inRetVal = VS_FALSE,
    inGetKey = 0;
    char szDispBuf[4][MESSAGE_SIZE + 1];

    //pdebug (("--fCustomerReceipt--"));

    vdFlushKeyboardBuffer();

    memset(szDispBuf, NULL_CH, sizeof(szDispBuf));
    vdClearNonTitleLines();
    vdPrepare3200LineChoice((char *) pchGetMsg(YESNO_MSG5x), 2, szDispBuf);
    vdReset_pchGetMsg();
    vdCreateOptWin3200(szDispBuf);  /* right-side keys.... */
    vdDisplayAt(obDisp.inHomeCol, obDisp.inSecondLineCOne, (char *) pchGetMsg(PRINT_MERCH_COPY_MSG), NO_CLEAR);
    vdReset_pchGetMsg();
    inGetKey = inWaitKeyWithBeep(inGetIdleTimeOut(), inGetPromptBeepDelay());
    //pdebug (("inGetKey=%d",inGetKey));
    if (inGetKey == KEY_e)
        inRetVal = VS_TRUE;

    vdDestroyOptWin3200();  /* reset to prior.... */
    vdClearNonTitleLines();

    pdebug(("inRetVal=%d", inRetVal));
    return (inRetVal);
}

/*********************************************************************************************
* @func int | inFlowPrintReceipt |
*       Transaction flow function to print the receipt
*
* @parm TRANSACTION_OBJECT *| pobTran
*       Transaction object
*
* @rdesc return values.
* @flag int    |  VS_ERR
* @flag int    |  VS_SUCCESS
* @end
**********************************************************************************************/

int inFlowPrintReceipt(TRANSACTION_OBJECT* pobTran) {
    int inRetval;
    int inPrintOption;
    unsigned long ulTimerCount;
    int inGetKey = 0;

    //pdebug (("--inFlowPrintReceipt--"));

    if (!fGetPrintReceipt(pobTran) || pobTran->fCounterPayTip)
        return(VS_SUCCESS);

    /* if the transaction is FPS qualified and the print option is prompt,
        prompt user if customer receipt should be printed */
    if ((pobTran->srBRec.inPrintOption == PRT_PROMPT) && fFPSQualified(pobTran)) {
        if (fCustomerReceipt(pobTran))
            pobTran->srBRec.inPrintOption = PRT_CUST;
        else
            pobTran->srBRec.inPrintOption = PRT_NONE;
    }

    if (pobTran->srBRec.inPrintOption == PRT_NONE)
        return(VS_SUCCESS);

    inPrintOption = pobTran->srBRec.inPrintOption;

    pdebug(("inPrintOption=%d", inPrintOption));

    if (vPFRSetPartFunc(__LINE__)) {
        /* Store the print both or single receipt option - this is lost if power fails while printing
            REMEMBER- This will not occur if we are in a recovery state */
        inAddExternalPfrData(PFR_PRINT_BOTH, (unsigned char *) &inPrintOption, sizeof(int));
    } else
        inGetExternalPfrData(PFR_PRINT_BOTH, (unsigned char *) &inPrintOption, sizeof(int));

    /* Set the power failure recovery state to just before receipt printing begin */
    inPFRStateStoreAll(PFR_BEGIN_PRINTING_RECEIPT, pobTran, 1, 1);

    vdFlushKeyboardBuffer();

    /* make one call to inPrintReceipt for each receipt needed;
    set the TRT Print Option to the type of receipt */
    if ((pobTran->srBRec.inPrintOption == PRT_BOTH_CONF_CUSTCOPY) || (pobTran->srBRec.inPrintOption == PRT_BOTH_AUTO_CUSTCOPY)) {
        pobTran->srBRec.inPrintOption = PRT_MERCH;

        if ((inRetval = inRunFormSegments(pobTran, BASE_RECEIPT)) != VS_ERR) {
            pobTran->srBRec.inPrintOption = inPrintOption;

            if (pobTran->srBRec.inPrintOption == PRT_BOTH_AUTO_CUSTCOPY) {
                pobTran->srBRec.inPrintOption = PRT_CUST;
                vdFlushKeyboardBuffer();
                vdDisplayMessageFromFile(TEAR_RECEIPT_MSG, STATUS_MSG);
                vdBeep();
                // Can't use inWaitKey() here because timeout sends back
                // KEY_CANCEL and we want Cancel key to abort and timeout
                // to finish printing
                ulTimerCount = set_itimeout(NO_CLOCK_HANDLE inGetPromptBeepDelay(), TM_SECONDS);
                while (CHECK_TIMEOUT(ulTimerCount) != 0) {
                    if (KBHIT() != 0) {
                        inGetKey = get_char();
                        break;
                    }
                }

                if (inGetKey != KEY_CANCEL)
                    inRetval = inRunFormSegments(pobTran, BASE_RECEIPT);
            } else if (fCustomerReceipt(pobTran)) {
                pobTran->srBRec.inPrintOption = PRT_CUST;
                inRetval = inRunFormSegments(pobTran, BASE_RECEIPT);
            }
        } /* end if print receipt != error */
    } /* end if print both */
    else
        inRetval = inRunFormSegments(pobTran, BASE_RECEIPT);

    /* The receipt has been printed, we can now return to an idle state */
    inPFRStateStoreAll(PFR_IDLE_STATE, pobTran, 0, 0);

    vdSetPrintReceipt(pobTran, VS_FALSE);
    return (inRetval);
}  /* end func inFlowPrintReceipt() */



/*********************************************************************************************
* @func int | inPreprint |
*       Transaction flow function to pre-print the receipt top
*
* @parm TRANSACTION_OBJECT *| pobTran
*       Transaction object
*
* @rdesc return values.
* @flag int    |  VS_ERR
* @flag int    |  VS_SUCCESS
* @end
**********************************************************************************************/

int inPreprint(TRANSACTION_OBJECT* pobTran) {
    int inRetval;


    inRetval = VS_SUCCESS;  /* Correct bug, as this may not be set by code below SDH */

    /* If Close Tab and close tab receipt is disabled */
    if ((inGGCode() == PRE_COMP) && (fGetCloseTabOptRec() == VS_FALSE))
        return(inRetval);
    /*
     *      Do not pre-print if ISDN, unless transaction is offline.
     */
    if (shGetCommLinkType() != ISDN_COMM || fGetOffline(pobTran)) {
        if (fGetPrePrint() && (pobTran->srBRec.inPrintOption > PRT_PROMPT))
            inRetval = inRunFormSegments(pobTran, RECEIPT_TOP);
    }

    return (inRetval);
} /* End of inPreprint () */

/*********************************************************************************************
* @func int | inPrinterCheck |
*       Form flow function to Check the printer status
*
* @parm TRANSACTION_OBJECT *| pobTran
*       Transaction object
*
* @rdesc return values.
* @flag int    |  VS_ERR
* @flag int    |  VS_SUCCESS
* @end
**********************************************************************************************/

int inPrinterCheck(TRANSACTION_OBJECT* pobTran) {
#ifdef IMAM_REMOVE
    if (!pobTran->fPreprinted) {
        if (inChkPrinterStatus(&obPrinter) != VS_SUCCESS)
            vdSetPrintReceipt(pobTran, VS_FALSE);
    }
#endif //IMAM_REMOVE
    return(VS_SUCCESS);
}

int PRTFUNCS_CODE_CHECK(char* a,char* b,short* c,char* d,unsigned char* e) {
    GET_VER(a, b, c, d, e);
    return 1;
}

